#!/usr/bin/perl
use strict;
use CGI::Fast;
use LWP::UserAgent;
use Image::ExifTool qw(:Public);
use JSON;
use DBI qw(:sql_types);

our $MAX_SIZE = 30000;
our $DB_FILE = 'db/exif.db';

my $ua = LWP::UserAgent->new(max_size => $MAX_SIZE);

my $dbh = DBI->connect('dbi:SQLite:dbname=' . $DB_FILE, '', '',
		       { RaiseError => 0, PrintError => 0 });

while (my $q = new CGI::Fast) {
    my $url = $q->param('url');
    unless ($url) {
	print $q->header('text/plain','403 Forbidden'), '403 Forbidden';
	next;
    }

    if (my $exif = get_exif_info($url)) {
	print_json($q, $exif->{json});
	next;
    }
    my $res = $ua->get($url);
    unless ($res->is_success) {
	print $q->header('text/plain','403 Forbidden'), '403 Forbidden';
	next;
    }
    my $info = ImageInfo(\$res->content);
    delete $info->{DataDump};
    delete $info->{ThumbnailImage};

    my $json = objToJson($info);
    print_json($q, $json);
    store_exif_info($url, $json);
}

sub print_json {
    my ($q, $json) = @_;
    $q->charset('utf-8');
    print $q->header('text/javascript');
    if (my $callback = $q->param('callback')) {
	print "$callback($json);\n";
    } elsif (my $var = $q->param('var')) {
	print "if (typeof($var) == 'undefined') $var = {};\n";
	print "$var.data = $json;\n";
	print "if (typeof($var.onload) == 'function') $var.onload($var.data);\n";
    } else {
	print $json;
    }
}

sub get_exif_info {
    my $url = shift;
    my $sth = $dbh->prepare("SELECT * FROM exif WHERE url=?");
    $sth->execute($url)
	or die "Select failed on SQL error " . $dbh->errstr;
    if (my $exif = $sth->fetchrow_hashref) {
	return $exif if time - $exif->{created_on} < 86400;
    }
}

sub store_exif_info {
    my ($url, $json) = @_;
    my $sth = $dbh->prepare("INSERT OR REPLACE INTO exif (url,json,created_on) VALUES (?,?,?)");
    $sth->bind_param(1, $url,  SQL_VARCHAR);
    $sth->bind_param(2, $json, SQL_VARCHAR);
    $sth->bind_param(3, time,  SQL_INTEGER);
    $sth->execute
	or die "Select failed on SQL error " . $dbh->errstr;
}

1;
